package com.zlp.netty.buffer;

import com.google.gson.Gson;
import org.junit.Test;

import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.URL;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.StandardCharsets;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Queue;

import static com.zlp.netty.buffer.ByteBufferUtil.debugAll;

/**
 * @author: zhulaiping
 * @time: 2022/8/10 14:34
 */
public class TestAllocate {

    public static void main(String[] args) {
        //java.nio.HeapByteBuffer  jvm堆内存，读写效率低，受GC的影响
        System.out.println(ByteBuffer.allocate(10).getClass());
        //java.nio.DirectByteBuffer 直接内存、读写效率高（少一次拷贝），分配的效率低
        System.out.println(ByteBuffer.allocateDirect(10).getClass());

        ByteBuffer buffer = ByteBuffer.allocate(10);
        byte[] bytes = new byte[]{'a','b','c'};
        buffer.put(bytes);
       /* buffer.flip(); //切换到读模式
        buffer.get(new byte[3]);
        System.out.println(buffer.toString());
        buffer.rewind();//从头开始读
        System.out.println((char)buffer.get());*/
        // mark && reset
        // mark 做一个标记，记录position的位置，reset将position重置到mark的位置
        buffer.flip();
        System.out.println((char) buffer.get());
        buffer.mark();
        System.out.println((char) buffer.get());
        System.out.println((char) buffer.get());
        buffer.reset();
        System.out.println((char) buffer.get());
        System.out.println((char) buffer.get());
    }

    //字符串与buffer的转换
    @Test
    public void String2Char(){

        //将数据写到buffer，并切换到读模式
        ByteBuffer buffer = StandardCharsets.UTF_8.encode("hello");
        debugAll(buffer);

        //将数据写到buffer，并切换到读模式
        ByteBuffer buffer2 = ByteBuffer.wrap("hello".getBytes());
        debugAll(buffer2);
    }

    //分段读
    @Test
    public void subsectionRead(){
        try (FileChannel channel = new RandomAccessFile("word.txt", "r").getChannel()) {
            ByteBuffer b1 = ByteBuffer.allocate(3);
            ByteBuffer b2 = ByteBuffer.allocate(3);
            ByteBuffer b3 = ByteBuffer.allocate(5);
            channel.read(new ByteBuffer[]{b1,b2,b3});
            b1.flip();
            b2.flip();
            b3.flip();
            debugAll(b1);
            debugAll(b2);
            debugAll(b3);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //分段写
    @Test
    public void subsectionWrite(){
        try (FileChannel channel = new RandomAccessFile("word2.txt", "rw").getChannel()) {
            ByteBuffer b1 = ByteBuffer.wrap("hello".getBytes());
            ByteBuffer b2 = ByteBuffer.wrap("world".getBytes());
            ByteBuffer b3 = ByteBuffer.wrap("您好".getBytes());
            channel.write(new ByteBuffer[]{b1,b2,b3});

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //buffer 实战案例
    @Test
    public void ee(){
        ByteBuffer buffer = ByteBuffer.allocate(32);
        buffer.put("Hello,world\nI am zhangsan\nHo".getBytes());
        split(buffer);
        buffer.put("w old are you\n".getBytes());
        split(buffer);
    }

    private void split(ByteBuffer buffer) {
        buffer.flip();//切换为读模式
        for (int i=0;i<buffer.limit();i++){
            if (buffer.get(i) == '\n') {
                int len = i + 1 - buffer.position();
                ByteBuffer target = ByteBuffer.allocate(len);
                for (int j=0;j<len;j++){
                    target.put(buffer.get());
                }
                debugAll(target);
            }
        }
        buffer.compact();
    }


}
